import React, {
  useState,
  useRef,
  useEffect,
  forwardRef,
  useImperativeHandle,
} from 'react';
import { Button, Tree, Modal, Input } from 'antd';
import EditorForm from './EditorForm';
const { Search } = Input;
const tds = [
  {
    title: '0-0',
    key: '0-0',
    children: [
      {
        title: '0-0-0',
        key: '0-0-0',
        children: [
          { title: '0-0-0-0', key: '0-0-0-0' },
          { title: '0-0-0-1', key: '0-0-0-1' },
          { title: '0-0-0-2', key: '0-0-0-2' },
        ],
      },
      {
        title: '0-0-1',
        key: '0-0-1',
        children: [
          { title: '0-0-1-0', key: '0-0-1-0' },
          { title: '0-0-1-1', key: '0-0-1-1' },
          { title: '0-0-1-2', key: '0-0-1-2' },
        ],
      },
      {
        title: '0-0-2',
        key: '0-0-2',
      },
    ],
  },
  {
    title: '0-1',
    key: '0-1',
    children: [
      { title: '0-1-0-0', key: '0-1-0-0' },
      { title: '0-1-0-1', key: '0-1-0-1' },
      { title: '0-1-0-2', key: '0-1-0-2' },
    ],
  },
  {
    title: '0-2',
    key: '0-2',
    children: [{ title: '0-2-1', key: '0-2-1' }],
  },
];
function flatTreeData(treeData) {
  return treeData.reduce((prev, cur) => {
    const { key, title, children = [] } = cur;
    return prev.concat([{ key, title }], flatTreeData(children));
  }, []);
}
function SearchTree({ onTreeDataChange = () => null }, ref) {
  useImperativeHandle(ref, () => ({
    getTreeData,
  }));
  const formRef = useRef(null);
  const [selectedKeys, setSelectedKeys] = useState([]);
  const [eidtorNode, setEidtorNode] = useState({});
  const [autoExpandParent, setAutoExpandParent] = useState(true);
  const [visible, toggleVisible] = useState(false);
  const [searchValue, setSearchValue] = useState('');
  const [expandedKeys, setExpandedKeys] = useState([]);
  const [treeData, setTreeData] = useState(tds);
  function handleSelectTreeNode(keys) {
    setSelectedKeys(keys);
  }
  function getTreeData() {
    return treeData;
  }
  function editorNodeByKey(tree, val, func) {
    for (let i in tree) {
      if (func(tree[i])) {
        tree[i].title = val.title;
      }
      if (tree[i].children) {
        editorNodeByKey(tree[i].children, val, func);
      }
    }
    return tree;
  }
  async function diectEditorTreeNode(nodeObj) {
    await setEidtorNode({ ...nodeObj });
    await toggleVisible(true);
    await formRef.current.setFormValue({ title: nodeObj.title });
  }
  function hideModal() {
    toggleVisible(false);
    setSelectedKeys([]);
    setEidtorNode({});
  }
  async function handleEditorConfirm() {
    const [key] = selectedKeys;
    const val = formRef.current.getFieldsValue();
    const nodeItem = { ...eidtorNode, ...val };
    const tr = editorNodeByKey(treeData, nodeItem, (data) => data.key === key);
    await setTreeData([...tr]);
    hideModal();
  }
  function getNodeParentKey(key, tree) {
    let parentKey;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some((item) => item.key === key)) {
          parentKey = node.key;
        } else if (getNodeParentKey(key, node.children)) {
          parentKey = getNodeParentKey(key, node.children);
        }
      }
    }
    return parentKey;
  }
  function handleSearch(e) {
    const { value } = e.target;
    setSearchValue(value);
    const flatD = flatTreeData(treeData);
    const expandedKeys = flatD
      .map((data) => {
        if (data.title.indexOf(value) > -1) {
          return getNodeParentKey(data.key, treeData);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    setExpandedKeys(expandedKeys);
    setAutoExpandParent(true);
  }
  function titleRender(nodeData) {
    const { title } = nodeData;
    const index = nodeData.title.indexOf(searchValue);
    const len = searchValue.length + index;
    const before = title.substr(0, index);
    const after = title.substr(len);
    if (index > -1 && !!searchValue) {
      return (
        <div>
          {before}
          <span style={{ color: 'red' }}>{searchValue}</span>
          {after}
          <Button type="link" onClick={() => diectEditorTreeNode(nodeData)}>
            修改
          </Button>
        </div>
      );
    }
    return (
      <div>
        <span>{title}</span>
        <Button type="link" onClick={() => diectEditorTreeNode(nodeData)}>
          修改
        </Button>
      </div>
    );
  }
  function filterTreeNode(node) {
    if (!!searchValue) {
      return node.title.includes(searchValue);
    }
    return false;
  }
  function handleExpand(expandedKeys) {
    setExpandedKeys(expandedKeys);
  }
  useEffect(() => {
    onTreeDataChange(treeData);
  }, [treeData]);
  return (
    <div>
      <div>
        <Search
          onChange={handleSearch}
          size="small"
          style={{ width: 200 }}
          allowClear
        />
      </div>
      <div>
        <Tree
          treeData={treeData}
          selectedKeys={selectedKeys}
          autoExpandParent={autoExpandParent}
          onSelect={handleSelectTreeNode}
          expandedKeys={expandedKeys}
          titleRender={titleRender}
          filterTreeNode={filterTreeNode}
          onExpand={handleExpand}
        />
      </div>
      <Modal
        visible={visible}
        title="修改节点名称"
        okText="修改"
        cancelText="取消"
        onCancel={hideModal}
        onOk={handleEditorConfirm}
      >
        <EditorForm ref={formRef} />
      </Modal>
    </div>
  );
}

const RefSearchTree = forwardRef(SearchTree);

export default RefSearchTree;
